package com.qijian.maindata.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qijian.common.annotation.Log;
import com.qijian.common.core.controller.BaseController;
import com.qijian.common.core.domain.AjaxResult;
import com.qijian.common.core.page.TableDataInfo;
import com.qijian.common.enums.ApprovalDescriptionEnum;
import com.qijian.common.enums.BusinessType;
import com.qijian.common.exception.ServiceException;
import com.qijian.common.utils.ObjectUtils;
import com.qijian.common.utils.SecurityUtils;
import com.qijian.common.utils.StringUtils;
import com.qijian.common.utils.VersionUtils;
import com.qijian.common.utils.bean.BeanUtils;
import com.qijian.common.utils.mybatis.WhereEntityTool;
import com.qijian.common.utils.uuid.IdUtils;
import com.qijian.maindata.domain.*;
import com.qijian.maindata.domain.query.*;
import com.qijian.maindata.domain.vo.*;
import com.qijian.maindata.service.IBomDetailService;
import com.qijian.maindata.service.IBomService;
import com.qijian.maindata.service.IItemService;
import com.qijian.maindata.service.ILineProcessItemService;
import com.qijian.maindata.tools.poi.ExcelCustomizationBomLineProcess;
import com.qijian.tool.domain.Storage;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * BOM明细Controller
 *
 * @author qijian
 * @date 2021-09-01
 */
@Api(tags = "工艺管理：BOM明细")
@RestController
@RequiredArgsConstructor
@RequestMapping("/maindata/bom/detail")
public class BomDetailController extends BaseController {

    private final IBomService bomService;
    private final IBomDetailService bomDetailService;
    private final ILineProcessItemService lineProcessItemService;

    private final IItemService itemService;

    /**
     * 查询BOM明细列表
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:list')")
    @GetMapping("/list")
    public TableDataInfo list(BomDetailQuery query, Page<BomDetail> page) {
        return getDataTable(bomDetailService.page(page, WhereEntityTool.invoke(query)));
    }

    @PreAuthorize("@ss.hasPermi('maindata:bom:list')")
    @GetMapping("/info/{bomId}")
    public TableDataInfo list(BomDetailInfoQuery query, Page<BomDetailInfoVo> page) {
        return getDataTable(bomDetailService.selectBomInfo(page, WhereEntityTool.invoke(query)));
    }



    private void sortBom(int num, int now, Map<Long, List<BomDetailVo>> bomResult, List<BomDetailVo> detailList, List<BomDetailVo> bomDetailList, List<LineProcessTimeVo> lineProcessList, List<LineProcessItemVo> lineProcessItemList) {
        if (now > num) {
            return;
        }

        for (BomDetailVo bom : detailList) {
            List<String> processNames = new LinkedList<>();
            List<LineProcessVo> lineProcess = bom.getProcessList();
            lineProcess.forEach(line -> {
                processNames.add(line.getProcessName());
                line.setCount(bom.getTotalQuantity().intValue());
                BeanUtils.copyProperties(bom, line.getBomDetail());
                line.setWorkTeam(line.getProcessWorkList().stream().map(LineProcessWork::getFactoryName).collect(Collectors.joining(",")));
                if (CollectionUtil.isNotEmpty(line.getProcessTimeList())) {
                    line.getProcessTimeList().forEach(processTime -> {
                        LineProcessTimeVo temp = new LineProcessTimeVo();
                        BeanUtils.copyProperties(processTime, temp);
                        temp.setLineProcess(line);
                        lineProcessList.add(temp);
                    });
                } else {
                    LineProcessTimeVo temp = new LineProcessTimeVo();
                    temp.setLineProcess(line);
                    lineProcessList.add(temp);
                }

                if (CollectionUtil.isNotEmpty(line.getProcessItemList())) {
                    line.getProcessItemList().forEach(pt -> {
                        LineProcessItemVo processItem = new LineProcessItemVo();
                        BeanUtils.copyProperties(pt, processItem);
                        processItem.setLineProcess(line);
                        lineProcessItemList.add(processItem);
                    });
                } else {
                    LineProcessItemVo processItem = new LineProcessItemVo();
                    processItem.setLineProcess(line);
                    lineProcessItemList.add(processItem);
                }
            });

            bom.setProcessNames(String.join("➢", processNames));
            bomDetailList.add(bom);
            now++;
            List<BomDetailVo> childList = bomResult.get(bom.getDetailId());
            if (CollectionUtil.isNotEmpty(childList)) {
                sortBom(num, now, bomResult, childList, bomDetailList, lineProcessList, lineProcessItemList);
            }
        }
    }


    /**
     * 获取BOM明细详细信息
     */
    @PreAuthorize("@ss.hasAnyPermi('maindata:bom:query,maindata:bom:list')")
    @GetMapping(value = "/hisLine/{bomId}")
    public AjaxResult getHisLine(@Validated @NotNull(message = "BomID错误") @PathVariable("bomId") Long bomId) {
        return AjaxResult.success(bomDetailService.getHisLineByBomId(bomId));
    }

    /**
     * 获取BOM明细详细信息
     */
    @PreAuthorize("@ss.hasAnyPermi('maindata:bom:query,maindata:bom:list')")
    @GetMapping(value = "/nc/{bomId}")
    public AjaxResult getNc(@Validated @NotNull(message = "BomID错误") @PathVariable("bomId") Long bomId) {
        return AjaxResult.success(bomDetailService.selectNc(bomId));
    }

    /**
     * 获取BOM明细详细信息
     */
//    @PreAuthorize("@ss.hasPermi('maindata:bom:query')")
    @GetMapping(value = "/{bomId}")
    public AjaxResult getInfo(@PathVariable("bomId") Long bomId) {
        BomDetailQuery query = new BomDetailQuery();
        query.setBomId(bomId);
        return AjaxResult.success(bomDetailService.selectVo(WhereEntityTool.invoke(query), 1));
    }

    @GetMapping(value = "/detail")
    public AjaxResult getInfoByBom(BomDetailQuery query) {
        query.setLineIdNotNull(true);
        return AjaxResult.success(bomDetailService.selectVo(WhereEntityTool.invoke(query), 1));
    }

    @GetMapping(value = "/line/detail")
    public AjaxResult getInfoByBomAndLine(BomDetailQuery query) {
        return AjaxResult.success(bomDetailService.selectBomAndLineVo(WhereEntityTool.invoke(query)));
    }

    /**
     * 工艺管理-员工收益 钻取Bom和数控件详情
     */
    @GetMapping(value = "/earn")
    public AjaxResult getInfo(BomDetailQuery query) {
        return AjaxResult.success(bomDetailService.selectVo(query));
    }

    /**
     * 获取BOM明细详细信息包含工时/工价/使用物料
     */
    @GetMapping(value = "/all/{bomId}")
    public AjaxResult getInfoAll(@PathVariable("bomId") Long bomId) {
        // BOM详情信息
        BomDetailQuery query = new BomDetailQuery();
        query.setBomId(bomId);
        Map<String, Object> map = new HashMap<>(2);
        List<BomDetailAllVo> bomDetailList = bomDetailService.selectAllVo(WhereEntityTool.invoke(query));
        List<Storage> files = bomDetailService.getFiles(bomId);
        List<Long> pIds = bomDetailList.stream().map(BomDetailAllVo::getPid).collect(Collectors.toList());

        bomDetailList.forEach(detail -> {
                    detail.setFiles(files.stream().filter(file -> file.getClassId().equals(detail.getDetailId())).collect(Collectors.toList()));
                    if (pIds.contains(detail.getDetailId())) {
                        detail.setIsLeaf(false);
                    } else {
                        detail.setIsLeaf(true);
                    }
                }
        );
        // 增加字符串拼接
        bomDetailList.forEach(detail -> {
                    String itemAttr = detail.getItemAttr();
                    if (StringUtils.isNotEmpty(itemAttr) && itemAttr.startsWith("[")) {
                        JSONArray jsonArray = new JSONArray(itemAttr);
                        String itemAttrStr = "";
                        String thickness = "";
                        for (Object obj : jsonArray) {
                            JSONObject json = new JSONObject(obj);
                            String key = json.getStr("name");
                            String value = json.getStr("value");
                            itemAttrStr += key + ":" + value + "/";
                            if ("厚".equals(key)) {
                                thickness = value;
                            }
                        }
                        if (StrUtil.isNotBlank(thickness)) {
                            detail.setThickness(thickness);
                        }
                        detail.setItemAttrStr(itemAttrStr);
                    }
                }
        );
        map.put("bomData", bomDetailList);

        // 零件

        // 查询使用外购件
        Set<Long> bomIds = new HashSet<>(bomDetailList.size());
        Set<Long> itemIdsNot = new HashSet<>(bomDetailList.size());
        bomDetailList.forEach(detail -> {
            bomIds.add(detail.getDetailId());
            itemIdsNot.add(detail.getItemId());
        });
        LineProcessItemQuery processItemQuery = new LineProcessItemQuery();
        processItemQuery.setBomIds(bomIds);
        processItemQuery.setItemIdsNot(itemIdsNot);
        processItemQuery.setLineIdIsNull(true);
        processItemQuery.setProcessIdIsNull(true);
//        Map<Long, List<LineProcessItem>> processItemList = lineProcessItemService.list(WhereEntityTool.invoke(processItemQuery)).stream().collect(Collectors.toMap(LineProcessItem::getBomId, Lists::newArrayList, ListUtils::union));
        Map<String, List<LineProcessItem>> processItemMap = new HashMap<>(16);
        lineProcessItemService.list(WhereEntityTool.invoke(processItemQuery)).forEach(action -> {
            List<LineProcessItem> temp = processItemMap.get(action.getBomId().toString());
            if (CollectionUtil.isEmpty(temp)) {
                temp = new ArrayList<>(16);
                processItemMap.put(action.getBomId().toString(), temp);
            }
            temp.add(action);

        });

        map.put("materials", processItemMap);
        return AjaxResult.success(map);
    }

    /**
     * 获取BOM明细详细信息包含工时/工价/使用物料
     */
    @GetMapping(value = "/bomTree/{bomId}")
    public AjaxResult getBomTree(@PathVariable("bomId") Long bomId) {
        // BOM详情信息
        BomDetailQuery query = new BomDetailQuery();
        query.setBomId(bomId);
        if (this.bomDetailService.lambdaQuery().eq(BomDetail::getDetailId, bomId).eq(BomDetail::getLevel, -1).count() > 0) {
            query.setLevel(-1);
        } else {
            query.setLevel(0);
        }

        Map<String, Object> map = new HashMap<>(2);
        List<BomDetailAllVo> bomDetailList = bomDetailService.selectAllVo(WhereEntityTool.invoke(query));
        if (bomDetailList == null || bomDetailList.size() == 0) {
            return AjaxResult.success(null);
        }

        List<Storage> files = bomDetailService.getFiles(bomId);
        bomDetailList.forEach(detail -> detail.setFiles(files.stream().filter(file -> file.getClassId().equals(detail.getDetailId())).collect(Collectors.toList())));
        map.put("bomData", bomDetailList);

        // 零件

        // 查询使用外购件
        Set<Long> bomIds = new HashSet<>(bomDetailList.size());
        Set<Long> itemIdsNot = new HashSet<>(bomDetailList.size());
        bomDetailList.forEach(detail -> {
            bomIds.add(detail.getDetailId());
            itemIdsNot.add(detail.getItemId());
        });
        LineProcessItemQuery processItemQuery = new LineProcessItemQuery();
        processItemQuery.setBomIds(bomIds);
        processItemQuery.setItemIdsNot(itemIdsNot);
        processItemQuery.setLineIdIsNull(true);
        processItemQuery.setProcessIdIsNull(true);
//        Map<Long, List<LineProcessItem>> processItemList = lineProcessItemService.list(WhereEntityTool.invoke(processItemQuery)).stream().collect(Collectors.toMap(LineProcessItem::getBomId, Lists::newArrayList, ListUtils::union));
        Map<String, List<LineProcessItem>> processItemMap = new HashMap<>(16);
        lineProcessItemService.list(WhereEntityTool.invoke(processItemQuery)).forEach(action -> {
            List<LineProcessItem> temp = processItemMap.get(action.getBomId().toString());
            if (CollectionUtil.isEmpty(temp)) {
                temp = new ArrayList<>(16);
                processItemMap.put(action.getBomId().toString(), temp);
            }
            temp.add(action);

        });

        map.put("materials", processItemMap);
        return AjaxResult.success(map);
    }

    @GetMapping(value = "/getChild")
    public AjaxResult getChild(BomDetailChildQuery childQuery) {
        // BOM详情信息
        BomDetailQuery query = new BomDetailQuery();
        query.setBomId(childQuery.getBomId());
        Map<String, Object> map = new HashMap<>(2);
        BomDetail bomDetail = bomDetailService.getById(childQuery.getDetailId());
        if (ObjectUtils.isNull(bomDetail)) {
            throw new ServiceException("E01:未找到Bom明细");
        }
        // 需要根据pid查
        query.setPid(bomDetail.getDetailId());
        // 同时需要将本节点返回
        QueryWrapper<BomDetailQuery> wapper = WhereEntityTool.invoke(query);
        wapper.or(wp -> wp.eq("detail_id", bomDetail.getDetailId()));

        List<BomDetailAllVo> bomDetailList = bomDetailService.selectAllVo(wapper);

        List<Storage> files = bomDetailService.getFiles(childQuery.getBomId());
        bomDetailList.forEach(detail -> detail.setFiles(files.stream().filter(file -> file.getClassId().equals(detail.getDetailId())).collect(Collectors.toList())));
        // 增加字符串拼接
        bomDetailList.forEach(detail -> {
                    String itemAttr = detail.getItemAttr();
                    if (StringUtils.isNotEmpty(itemAttr) && itemAttr.startsWith("[")) {
                        JSONArray jsonArray = new JSONArray(itemAttr);
                        String itemAttrStr = "";
                        String thickness = "";
                        for (Object obj : jsonArray) {
                            JSONObject json = new JSONObject(obj);
                            String key = json.getStr("name");
                            String value = json.getStr("value");
                            itemAttrStr += key + ":" + value + "/";
                            if ("厚".equals(key)) {
                                thickness = value;
                            }
                        }
                        if (StrUtil.isNotBlank(thickness)) {
                            detail.setThickness(thickness);
                        }
                        detail.setItemAttrStr(itemAttrStr);
                    }
                }
        );
        map.put("bomData", bomDetailList);

        // 零件

        // 查询使用外购件
        Set<Long> bomIds = new HashSet<>(bomDetailList.size());
        Set<Long> itemIdsNot = new HashSet<>(bomDetailList.size());
        bomDetailList.forEach(detail -> {
            bomIds.add(detail.getDetailId());
            itemIdsNot.add(detail.getItemId());
        });
        Map<String, List<LineProcessItem>> processItemMap = new HashMap<>(16);
        if (CollectionUtil.isNotEmpty(bomIds)) {
            LineProcessItemQuery processItemQuery = new LineProcessItemQuery();
            processItemQuery.setBomIds(bomIds);
            processItemQuery.setItemIdsNot(itemIdsNot);
            processItemQuery.setLineIdIsNull(true);
            processItemQuery.setProcessIdIsNull(true);
            lineProcessItemService.list(WhereEntityTool.invoke(processItemQuery)).forEach(action -> {
                List<LineProcessItem> temp = processItemMap.get(action.getBomId().toString());
                if (CollectionUtil.isEmpty(temp)) {
                    temp = new ArrayList<>(16);
                    processItemMap.put(action.getBomId().toString(), temp);
                }
                temp.add(action);

            });
        }
        map.put("materials", processItemMap);
        return AjaxResult.success(map);
    }


    @GetMapping(value = "/count")
    public AjaxResult count(BomDetailQuery query) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.set("self", bomDetailService.count(WhereEntityTool.invoke(query)));
        query.setDetailId(null);
        jsonObject.set("all", bomDetailService.count(WhereEntityTool.invoke(query)));
        return AjaxResult.success(jsonObject);
    }

    /**
     * 获取BOM明细详细信息含工序
     */
    @PreAuthorize("@ss.hasAnyPermi('maindata:bom:query,maindata:project:list')")
    @GetMapping(value = "/process/{bomId}")
    public AjaxResult process(@PathVariable("bomId") Long bomId) {
//        BomDetailQuery query = new BomDetailQuery();
//        query.setBomId(bomId);
//        List<BomDetailVo> bomDetailList = bomDetailService.selectVo(WhereEntityTool.invoke(query));
//        Set<Long> lineIds = new HashSet<>(bomDetailList.size());
//        Map<String, BomDetailVo> lineMap = new HashMap<>(bomDetailList.size());
//        bomDetailList.forEach(action -> {
//            if (ObjectUtil.isNotNull(action.getLineId())) {
//                lineIds.add(action.getLineId());
//            }
//            action.setProcessList(new ArrayList<>(16));
//            lineMap.put(action.getDetailId().toString() + action.getLineId(), action);
//        });
//
//        LineProcessQuery processQuery = new LineProcessQuery();
//        processQuery.setLineIds(lineIds);
//        processQuery.setIsDefault(true);
//        List<LineProcessVo> processList = lineProcessService.listVo(WhereEntityTool.invoke(processQuery));
//        processList.forEach(action -> {
//            // 查询所属该工艺线路的BOM
//            Map<String, BomDetailVo> temp = lineMap.entrySet().stream()
//                    .filter((e) -> e.getKey().contains(action.getLineId().toString()))
//                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
//            // 添加工艺
//            temp.forEach((key, value) -> {
//                value.getProcessList().add(action);
//            });
//        });
        BomDetailQuery query = new BomDetailQuery();
        query.setBomId(bomId);
        List<BomDetailVo> detailVoList = bomDetailService.listVo(WhereEntityTool.invoke(query));
        detailVoList.forEach(detail -> {
            // 去除备选方案
            List<LineProcessVo> processList = detail.getProcessList();
            detail.setProcessList(processList.stream().filter(LineProcess::getIsDefault).collect(Collectors.toList()));
        });
        return AjaxResult.success(detailVoList);
    }

    @PreAuthorize("@ss.hasPermi('maindata:bom:copy')")
    @GetMapping(value = "/copy/{bomId}")
    public AjaxResult copy(@PathVariable("bomId") Long bomId) {
        // BOM
        Bom bom = bomService.getById(bomId);
        if (ObjectUtil.isNull(bom) || ObjectUtil.isNull(bom.getBomId())) {
            throw new ServiceException("E01:BOM信息错误！");
        }
        bom.setBomCode("BOM-" + String.format("%06d", bomService.count() + 1));
        bom.setBomId(null);
        bom.setCreateBy(null);
        bom.setCreateTime(null);
        String maxVersion = bomService.maxVersion(bom.getItemCode());
        bom.setBomVersion(VersionUtils.autoUpgradeVersion(maxVersion));
        bomService.save(bom);
        // 明细
        BomDetailQuery query = new BomDetailQuery();
        query.setBomId(bomId);
        List<BomDetail> details = bomDetailService.list(WhereEntityTool.invoke(query));
        Map<String, BomDetail> noMap = new HashMap<>(details.size());
        if (CollectionUtil.isNotEmpty(details)) {
            for (BomDetail bomDetail : details) {
                bomDetail.setBomId(bom.getBomId());
                bomDetail.setDetailId(IdUtils.singletonSnowId());
                noMap(noMap, bomDetail);
            }
        }
        return AjaxResult.success(bomDetailService.saveBatch(details));
    }

    /**
     * 层级Map
     *
     * @param noMap     /
     * @param bomDetail /
     */
    private void noMap(Map<String, BomDetail> noMap, BomDetail bomDetail) {
        noMap.put(bomDetail.getDetailCode(), bomDetail);
        if (bomDetail.getDetailCode().contains(".")) {
            int lastIndex = bomDetail.getDetailCode().lastIndexOf(".");
            String no = bomDetail.getDetailCode().substring(0, lastIndex);
            BomDetail parent = noMap.get(no);
            if (ObjectUtil.isNull(parent)) {
                throw new ServiceException("E01:编号：" + no + "  前置节点查询失败！");
            }
            bomDetail.setPid(parent.getDetailId());
        }
    }

    /**
     * 新增BOM明细
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:add')")
    @Log(title = "BOM明细", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody List<BomDetail> bomDetails) {
        if (CollectionUtil.isEmpty(bomDetails)) {
            throw new ServiceException("E01:BOM层级为空！");
        }
        //检测bom_status,设置审核状态
        Set<Long> bomIds = bomDetails.stream().map(BomDetail::getBomId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (bomIds.size() > 0) {
            BomQuery bomQ = new BomQuery();
            bomQ.setIds(bomIds);
            bomQ.setNeqApprovalStatus(ApprovalDescriptionEnum.C);
            List<Bom> bomList = bomService.list(WhereEntityTool.invoke(bomQ));
            List<Bom> updateBom = new ArrayList<>();
            bomList.forEach(b -> {
                //看bom的三个status是否都为true
                com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSONObject.parseObject(b.getBomStatus());
                if (json.containsKey("BOM") && json.containsKey("线路") && json.containsKey("定额")) {
                    if (json.getBoolean("BOM") && json.getBoolean("线路") && json.getBoolean("定额")) {
                        Bom temp = new Bom();
                        temp.setBomId(b.getBomId());
                        temp.setApprovalBy(SecurityUtils.getNickName());
                        temp.setApprovalStatus(ApprovalDescriptionEnum.C);
                        temp.setApprovalTime(new Date());
                        updateBom.add(temp);
                    }
                }
            });
            if (updateBom.size() > 0) {
                bomService.updateBatchById(updateBom);
            }
        }
        Map<String, BomDetail> noMap = new HashMap<>(bomDetails.size());
        Set<Long> idsNot = new HashSet<>(16);
        for (BomDetail bomDetail : bomDetails) {
            bomDetail.setIsDel(false);
            if (ObjectUtil.isNull(bomDetail.getDetailId())) {
                bomDetail.setDetailId(IdUtils.singletonSnowId());
            } else {
                idsNot.add(bomDetail.getDetailId());
            }
            noMap(noMap, bomDetail);
        }
        if (CollectionUtil.isNotEmpty(idsNot)) {
            BomDetailQuery query = new BomDetailQuery();
            query.setBomId(bomDetails.get(0).getBomId());
            query.setIdsNot(idsNot);
            // 根据查询条件中的detailIdToGetPid做为pid 删除时加上这个条件
            query.setPid(getPid(bomDetails));
            bomDetailService.remove(WhereEntityTool.invoke(query));
        }
        bomDetailService.saveOrUpdateBatch(bomDetails);
        return toAjax(bomDetails.size());
    }

    @PreAuthorize("@ss.hasPermi('maindata:bom:add')")
    @Log(title = "BOM明细", businessType = BusinessType.INSERT)
    @PostMapping("/addNew")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addNew(@RequestBody List<BomDetailVo> bomDetails) {
        if (CollectionUtil.isEmpty(bomDetails)) {
            throw new ServiceException("E01:BOM层级为空！");
        }
        //对数据进行去重
        bomDetails = bomDetails.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getDetailCode()))), ArrayList::new));

        //更新物料属性
        List<Item> items = new ArrayList<>();
        bomDetails.stream().forEach(e->{
            Item item = new Item();
            item.setItemId(e.getItemId());
            item.setItemAttr(e.getItemAttr());
            items.add(item);
        });
        itemService.updateBatchById(items);
        //检测bom_status,设置审核状态
        Set<Long> bomIds = bomDetails.stream().map(BomDetail::getBomId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (bomIds.size() > 0) {
            BomQuery bomQ = new BomQuery();
            bomQ.setIds(bomIds);
            bomQ.setNeqApprovalStatus(ApprovalDescriptionEnum.C);
            List<Bom> bomList = bomService.list(WhereEntityTool.invoke(bomQ));
            List<Bom> updateBom = new ArrayList<>();
            bomList.forEach(b -> {
                //看bom的三个status是否都为true
                com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSONObject.parseObject(b.getBomStatus());
                if (json.containsKey("BOM") && json.containsKey("线路") && json.containsKey("定额")) {
                    if (json.getBoolean("BOM") && json.getBoolean("线路") && json.getBoolean("定额")) {
                        Bom temp = new Bom();
                        temp.setBomId(b.getBomId());
                        temp.setApprovalBy(SecurityUtils.getNickName());
                        temp.setApprovalStatus(ApprovalDescriptionEnum.C);
                        temp.setApprovalTime(new Date());
                        updateBom.add(temp);
                    }
                }
            });
            if (updateBom.size() > 0) {
                bomService.updateBatchById(updateBom);
            }
        }
        Map<String, BomDetail> noMap = new HashMap<>(bomDetails.size());
        Set<Long> idsNot = new HashSet<>(16);
        for (BomDetail bomDetail : bomDetails) {
            bomDetail.setIsDel(false);
            if (ObjectUtil.isNull(bomDetail.getDetailId())) {
                bomDetail.setDetailId(IdUtils.singletonSnowId());
            } else {
                idsNot.add(bomDetail.getDetailId());
            }
            noMap(noMap, bomDetail);
        }
        List<BomDetail> bomDetailsCopy = BeanUtils.copyToList(bomDetails, BomDetail.class);
        if (CollectionUtil.isNotEmpty(idsNot)) {
            BomDetailQuery query = new BomDetailQuery();
            query.setBomId(bomDetails.get(0).getBomId());
            query.setIdsNot(idsNot);
            // 根据查询条件中的detailIdToGetPid做为pid 删除时加上这个条件
            query.setPid(getPid(bomDetailsCopy));
            bomDetailService.remove(WhereEntityTool.invoke(query));
        }
        bomDetailService.saveOrUpdateBatch(bomDetailsCopy);
        return toAjax(bomDetails.size());
    }

    /**
     * 根据查询条件中的detailIdToGetPid做为pid 删除时加上这个条件
     *
     * @param bomDetails
     * @return
     */
    Long getPid(List<BomDetail> bomDetails) {
        if (ObjectUtils.isNotNull(bomDetails.get(0).getDetailIdToGetPid())) {
            return bomDetails.get(0).getDetailIdToGetPid();
        }
        return null;
    }

    /**
     * 修改BOM明细
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:edit')")
    @Log(title = "BOM明细", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BomDetail bomDetail) {
        return toAjax(bomDetailService.updateById(bomDetail));
    }

    /**
     * 修改BOM明细
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:edit')")
    @Log(title = "BOM明细批量", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/batchEdit")
    public AjaxResult batchEdit(@RequestBody List<BomDetail> resources) {
        if (CollUtil.isEmpty(resources)) {
            throw new ServiceException("E01:保存数据为空");
        }
        return toAjax(bomDetailService.updateBatchById(resources));
    }

    /**
     * 删除BOM明细
     */
    @PreAuthorize("@ss.hasPermi('maindata:bom:remove')")
    @Log(title = "BOM明细", businessType = BusinessType.DELETE)
    @DeleteMapping("/{detailIds}")
    public AjaxResult remove(@PathVariable List<Long> detailIds) {
        return toAjax(bomDetailService.removeByIds(detailIds));
    }

    @GetMapping("/export/lineProcess/{bomDetailId}")
    public void exportLineProcess(@PathVariable Long bomDetailId, HttpServletResponse response) {
        new ExcelCustomizationBomLineProcess().exportExcel(response, bomDetailService.getBomDetailLineProcess(bomDetailId));
    }

    @GetMapping("/export/lineProcessType/{bomId}")
    public void exportLineProcessType(@PathVariable Long bomId, HttpServletResponse response) {
        new ExcelCustomizationBomLineProcess().exportExcel(response, bomDetailService.getBomDetailLineProcessType(bomId));
    }

}
